#include "TextureLoader.h"
#include "Constants.h"

TextureLoader::TextureLoader()
{
}

TextureLoader::~TextureLoader()
{
}

void TextureLoader::loadTextures()
{
    topTextures[0] = loadBmp("data/images/Stone Top.bmp");
    sideTextures[0] = loadBmp("data/images/Stone Side.bmp");
    topTextures[1] = loadBmp("data/images/Grass Top.bmp");
    sideTextures[1] = loadBmp("data/images/Grass Side.bmp");
    topTextures[2] = loadBmp("data/images/Dirt Top.bmp");
    sideTextures[2] = loadBmp("data/images/Dirt Side.bmp");
    topTextures[3] = loadBmp("data/images/Water Top.bmp");
    sideTextures[3] = loadBmp("data/images/Water Side.bmp");	
}

SDL_Surface * TextureLoader::loadSurface(char * fileName)
{
	Uint8 * rowhi, * rowlo;
	Uint8 * tmpbuf, tmpch;

	int i, j;
	SDL_Surface * image;
		
	image = SDL_LoadBMP(fileName);
	if(image == NULL)
	{
		fprintf(stderr, "Unable to load %s: %s\n", fileName, SDL_GetError());
		return NULL;
	}
	
	//Crazy GL upside down BGR to RGB conversion
	tmpbuf = (Uint8 *)malloc(image->pitch);
	if(tmpbuf == NULL)
	{
		fprintf(stderr, "Out of memory\n");
		return NULL;
	}
	rowhi = (Uint8 *)image->pixels;
	rowlo = rowhi + (image->h * image->pitch) - image->pitch;
	for (i=0; i<image->h/2; ++i)
	{
		for (j=0; j<image->w; ++j)
		{
			tmpch = rowhi[j*3];
			rowhi[j*3] = rowhi[j*3+2];
			rowhi[j*3+2] = tmpch;
			tmpch = rowlo[j*3];
			rowlo[j*3] = rowlo[j*3+2];
			rowlo[j*3+2] = tmpch;
		}
		memcpy(tmpbuf, rowhi, image->pitch);
		memcpy(rowhi, rowlo, image->pitch);
		memcpy(rowlo, tmpbuf, image->pitch);
		rowhi += image->pitch;
		rowlo -= image->pitch;	
	}
	free(tmpbuf);
	
	return image;
}

GLuint TextureLoader::loadBmp(char * fileName)
{
	SDL_Surface * surface = loadSurface(fileName);
	
	if(!surface) //there has been an error
	{
		SDL_Quit();
		exit(1);
	}
	
	GLuint texture;
	glGenTextures(1, &texture);
	glBindTexture(GL_TEXTURE_2D, texture);
	
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	
	glTexImage2D(GL_TEXTURE_2D, 0, 3, surface->w, surface->h, 0, GL_RGB, GL_UNSIGNED_BYTE, surface->pixels);
	
	return texture;	
}
